//package com.openlogic.common.datasource.interceptor;
//
//import java.util.List;
//import java.util.stream.Collectors;
//
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//
//import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
//import com.openlogic.common.datasource.handler.OpenLogicTenantLineHandler;
//
//import net.sf.jsqlparser.JSQLParserException;
//import net.sf.jsqlparser.expression.Expression;
//import net.sf.jsqlparser.expression.Parenthesis;
//import net.sf.jsqlparser.expression.StringValue;
//import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
//import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
//import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
//import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
//import net.sf.jsqlparser.expression.operators.relational.InExpression;
//import net.sf.jsqlparser.expression.operators.relational.ItemsList;
//import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
//import net.sf.jsqlparser.parser.CCJSqlParserUtil;
//import net.sf.jsqlparser.schema.Column;
//import net.sf.jsqlparser.schema.Table;
//import net.sf.jsqlparser.statement.delete.Delete;
//import net.sf.jsqlparser.statement.insert.Insert;
//import net.sf.jsqlparser.statement.select.AllColumns;
//import net.sf.jsqlparser.statement.select.AllTableColumns;
//import net.sf.jsqlparser.statement.select.FromItem;
//import net.sf.jsqlparser.statement.select.PlainSelect;
//import net.sf.jsqlparser.statement.select.Select;
//import net.sf.jsqlparser.statement.select.SelectExpressionItem;
//import net.sf.jsqlparser.statement.select.SelectItem;
//import net.sf.jsqlparser.statement.select.SubSelect;
//import net.sf.jsqlparser.statement.update.Update;
//
///**
//* @ClassName: TenantLineInnerInterceptor
//* @Description: 租户拦截器
//* @author weiyongpeng
//* @date 2025年2月1日 上午7:10:40
// */
//public class OpenLogicTenantLineInnerInterceptor extends com.baomidou.mybatisplus.solon.plugins.inner.TenantLineInnerInterceptor{
//
//	private final OpenLogicTenantLineHandler tenantLineHandler;
//
//    public OpenLogicTenantLineInnerInterceptor(final OpenLogicTenantLineHandler tenantLineHandler) {
//        this.tenantLineHandler = tenantLineHandler;
//        super.setTenantLineHandler(tenantLineHandler);
//    }
//    
//    /**
//     * 处理条件
//     */
//    @Override
//	protected Expression builderExpression(Expression currentExpression, List<Table> tables, String whereSegment) {
//    	if (CollectionUtils.isEmpty(tables)) {
//            return currentExpression;
//        } else {
//        	// 拼接列名
//            Expression tenantId = this.tenantLineHandler.getTenantId();
//            Expression commonTenantId = this.tenantLineHandler.getCommonTenantId();
//            List<EqualsTo> equalsTos = tables.stream()
//                    .filter((x) -> !this.tenantLineHandler.ignoreTable(x.getName()) && !this.tenantLineHandler.isCommonTable(x.getName()))
//                    .map((item) -> new EqualsTo(this.getAliasColumn(item), tenantId))
//                    .collect(Collectors.toList());
//
//            // 拼接列值
//            List<InExpression> inExpressions = tables.stream()
//                    .filter((x) -> !this.tenantLineHandler.ignoreTable(x.getName()) && this.tenantLineHandler.isCommonTable(x.getName()))
//                    .map((item) -> {
//                        InExpression inExpression = new InExpression();
//                        inExpression.setLeftExpression(this.getAliasColumn(item));
//                        inExpression.setRightExpression(commonTenantId);
//                        return inExpression;
//                    }).collect(Collectors.toList());
//
//            if (CollectionUtils.isEmpty(equalsTos) && CollectionUtils.isEmpty(inExpressions)) {
//                return currentExpression;
//            } else {
//                Expression injectExpression = CollectionUtils.isNotEmpty(equalsTos) ? equalsTos.get(0) : inExpressions.get(0);
//                for (int i = 1; i < equalsTos.size(); ++i) {
//                    injectExpression = new AndExpression(injectExpression, equalsTos.get(i));
//                }
//                for (int i = equalsTos.size() > 0 ? 0 : 1; i < inExpressions.size(); ++i) {
//                    injectExpression = new AndExpression(injectExpression, inExpressions.get(i));
//                }
//                if (currentExpression == null) {
//                    return injectExpression;
//                } else {
//                    return currentExpression instanceof OrExpression ? new AndExpression(new Parenthesis(currentExpression), injectExpression) : new AndExpression(currentExpression, injectExpression);
//                }
//            }
//        }
//	}
//
//    /**
//     * insert 语句处理
//     */
//	@Override
//    protected void processInsert(Insert insert, int index, String sql, Object obj) {
//        if (!this.tenantLineHandler.ignoreTable(insert.getTable().getName())) {
//            List<Column> columns = insert.getColumns();
//            String tableName = insert.getTable().getName();
//            if (!CollectionUtils.isEmpty(columns)) {
//                String tenantIdColumn = this.tenantLineHandler.getTenantIdColumn();
//                if (!this.tenantLineHandler.ignoreInsert(columns, tenantIdColumn)) {
//                    columns.add(new Column(tenantIdColumn));
//                    List<Expression> duplicateUpdateColumns = insert.getDuplicateUpdateExpressionList();
//                    if (CollectionUtils.isNotEmpty(duplicateUpdateColumns)) {
//                        EqualsTo equalsTo = new EqualsTo();
//                        equalsTo.setLeftExpression(new StringValue(tenantIdColumn));
//                        equalsTo.setRightExpression(this.getTenantId(tableName));
//                        duplicateUpdateColumns.add(equalsTo);
//                    }            
//                    Select select = insert.getSelect();
//                    if (select != null) {
//                    	String selectStr = select.toString();
//                    	if(selectStr.toUpperCase().contains("UNION")) {
//                    		String[] selectArr;
//                    		if(selectStr.toUpperCase().contains("UNION ALL")) {
//                        		selectArr = selectStr.toUpperCase().split("UNION ALL");
//                        	}else {
//                        		selectArr = selectStr.toUpperCase().split("UNION");
//                        	}
//                    		for(int i=0;i<selectArr.length;i++) {
//                    			Select s1 = null; 
//								 try {
//									s1 = (Select) CCJSqlParserUtil.parse(selectArr[i]);
//								} catch (JSQLParserException e) {
//									e.printStackTrace();
//								}
//							 PlainSelect plainSelect = (PlainSelect) s1.getSelectBody();
//	                   	     FromItem fromItem = plainSelect.getFromItem();
//	                   	     if (fromItem instanceof Table) {
//	                   	    	Table fromTable = (Table) fromItem;
//	                   	    	if(fromTable.getName().toUpperCase().equals("DUAL")) {
//	                   	    		processPlainSelect(plainSelect,null);
//	                   	    		//新增代码：针对where后面带条件判断的语句
//	                   	    		String plainSelectString = plainSelect.toString();
//	                   	    		if(plainSelectString.toUpperCase().contains("AND DUAL.TENANT_ID")) {
//	                   	    			int endIndex = plainSelectString.toUpperCase().indexOf("AND DUAL.TENANT_ID");
//	                   	    			String plainSelectSubString = plainSelectString.substring(0, endIndex);//去掉AND dual.tenant_id
//	                   	    			Select subSelect = null;
//	                   	    			try {
//		   									subSelect = (Select) CCJSqlParserUtil.parse(plainSelectSubString);
//		   									plainSelect = (PlainSelect) subSelect.getSelectBody();
//		   									appendCustomSelectItem(plainSelect.getSelectItems(), fromTable);//添加tenant_id的值
//		   									select = (Select)CCJSqlParserUtil.parse(plainSelect.toString());
//		   									insert.setSelect(select);
//	                   	    			} catch (JSQLParserException e) {
//		   									e.printStackTrace();
//		   								}
//	                   	    		}else {
//	                   	    			//针对where后面不带条件判断的语句
//	                   	    			plainSelect.setWhere(null);
//	                       	    		appendCustomSelectItem(plainSelect.getSelectItems(), fromTable);
//	                   	    		}
////	                   	    		plainSelect.setWhere(null);
////	                   	    		appendCustomSelectItem(plainSelect.getSelectItems(), fromTable);
//	                   	    	}else {
//	                   	    		// fixed gitee pulls/141 duplicate update
//	                   	            processPlainSelect(plainSelect,null);
//	                   	            appendSelectItem(plainSelect.getSelectItems());
//	                   	    	}
//	                	            
//	                	        } else if (fromItem instanceof SubSelect) {
//	                	            SubSelect subSelect = (SubSelect) fromItem;
//	                	            appendSelectItem(plainSelect.getSelectItems());
//	                	            processInsertSelect(subSelect.getSelectBody(), null);
//	                	        }
//	                   	     	selectArr[i] = plainSelect.toString();
//                    		}
//                    		try {
//								select = (Select) CCJSqlParserUtil.parse(StringUtils.join(selectArr," UNION "));
//								insert.setSelect(select);
//                    		} catch (JSQLParserException e) {
//								e.printStackTrace();
//							}
//                    		
//                    	}else {
//	                       	 PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
//	                   	     FromItem fromItem = plainSelect.getFromItem();
//	                   	     if (fromItem instanceof Table) {
//	                   	    	Table fromTable = (Table) fromItem;
//	                   	    	if(fromTable.getName().toUpperCase().equals("DUAL")) {
//	                   	    		processPlainSelect(plainSelect, null);
//	                   	    		//新增代码：针对where后面带条件判断的语句
//	                   	    		String plainSelectString = plainSelect.toString();
//	                   	    		if(plainSelectString.toUpperCase().contains("AND DUAL.TENANT_ID")) {
//	                   	    			int endIndex = plainSelectString.toUpperCase().indexOf("AND DUAL.TENANT_ID");
//	                   	    			String plainSelectSubString = plainSelectString.substring(0, endIndex);//去掉AND dual.tenant_id
//	                   	    			Select subSelect = null;
//	                   	    			try {
//		   									subSelect = (Select) CCJSqlParserUtil.parse(plainSelectSubString);
//		   									plainSelect = (PlainSelect) subSelect.getSelectBody();
//		   									appendCustomSelectItem(plainSelect.getSelectItems(), fromTable);//添加tenant_id的值
//		   									select = (Select)CCJSqlParserUtil.parse(plainSelect.toString());
//		   									insert.setSelect(select);
//	                   	    			} catch (JSQLParserException e) {
//		   									e.printStackTrace();
//		   								}
//	                   	    		}else {
//	                   	    			//针对where后面不带条件判断的SQL语句
//	                   	    			plainSelect.setWhere(null);
//	                       	    		appendCustomSelectItem(plainSelect.getSelectItems(), fromTable);
//	                   	    		}
//	                   	    		
//	                   	    	}else {
//	                   	    		//针对没有UNION关键字和DUAL虚拟表的SQL语句
//	                   	            processPlainSelect(plainSelect, null);
//	                   	            appendSelectItem(plainSelect.getSelectItems());
//	                   	    	}
//                	          //针对多个select嵌套的SQL语句（由select语句代替表名）
//	            	        } else if (fromItem instanceof SubSelect) {
////	                	            SubSelect subSelect = (SubSelect) fromItem;
////	                	            appendSelectItem(plainSelect.getSelectItems());
////	                	            processInsertSelect(subSelect.getSelectBody());//会在嵌套的select语句中再次添加tenant_id字段，从而报错：ORA-00918: 未明确定义列
//	            	        	//以下两行代码替换上面三行代码
//	            	        	appendTenantIdValue(plainSelect.getSelectItems());
//                	            processPlainSelect(plainSelect, null);//避免在嵌套的select语句中再次添加tenant_id字段
//	            	        }
//                    	}
//                       //this.processInsertSelect(select.getSelectBody());
//                    	
//                      //针对insert中不含select语句的SQL	
//                    } else {	
//                        if (insert.getItemsList() == null) {
//                            throw ExceptionUtils.mpe("Failed to process multiple-table update, please exclude the tableName or statementId", new Object[0]);
//                        }
//
//                        ItemsList itemsList = insert.getItemsList();
//                        if (itemsList instanceof MultiExpressionList) {
//                            ((MultiExpressionList) itemsList).getExpressionLists().forEach((el) -> {
//                                el.getExpressions().add(this.getTenantId(tableName));
//                            });
//                        } else {
//                            ((ExpressionList) itemsList).getExpressions().add(this.getTenantId(tableName));
//                        }
//                    }
//                }
//            }
//        }
//    }
//
//    /**
//     * update 语句处理
//     */
//    @Override
//    protected void processUpdate(Update update, int index, String sql, Object obj) {
//        final Table table = update.getTable();
//        // 忽略控制
//        if (tenantLineHandler.ignoreTable(table.getName()))
//            return;
//        // 混合租户控制
//		if (this.tenantLineHandler.isCommonTable(table.getName())/* && this.tenantLineHandler.isLessor() */)
//            update.setWhere(this.inExpression(table, update.getWhere()));
//        else
//            update.setWhere(this.andExpression(table, update.getWhere(), null));
//    }
//
//    /**
//     * delete 语句处理
//     */
//    @Override
//    protected void processDelete(Delete delete, int index, String sql, Object obj) {
//        final Table table = delete.getTable();
//        // 忽略控制
//        if (tenantLineHandler.ignoreTable(delete.getTable().getName()))
//            return;
//        // 混合租户控制
//		if (this.tenantLineHandler.isCommonTable(table.getName())/* && this.tenantLineHandler.isLessor() */)
//            delete.setWhere(this.inExpression(table, delete.getWhere()));
//        else
//            delete.setWhere(this.andExpression(table, delete.getWhere(), null));
//    }
//
//    /**
//    * 描述：insert -> insert | tenant 
//    * @Title: getTenantId
//    * @param tableName
//    * @return
//    * @author weiyongpeng
//    * @date  2025年2月1日 上午7:20:51
//     */
//    protected Expression getTenantId(String tableName) {
//        return tenantLineHandler.isCommonTable(tableName)
//                ? this.tenantLineHandler.getMixTenantId()
//                : this.tenantLineHandler.getTenantId();
//    }
//
//    /**
//    * 描述：delete/update -> where | common tenant
//    * @Title: inExpression
//    * @param table
//    * @param where
//    * @return
//    * @author weiyongpeng
//    * @date  2025年2月1日 上午7:20:05
//     */
//    protected Expression inExpression(Table table, Expression where) {
//        //获得where条件表达式
//        InExpression inExpression = new InExpression();
//        inExpression.setLeftExpression(this.getAliasColumn(table));
//        inExpression.setRightExpression(this.tenantLineHandler.getCommonTenantId());
//        if (null != where)
//            return where instanceof OrExpression
//                    ? new AndExpression(inExpression, new Parenthesis(where))
//                    : new AndExpression(inExpression, where);
//        return inExpression;
//    }
//    
//    /**
//    * 描述：添加tenant_id的值
//    * @Title: appendCustomSelectItem
//    * @param selectItems
//    * @param fromTable
//    * @author weiyongpeng
//    * @date  2025年2月1日 上午7:20:17
//     */
//    protected void appendCustomSelectItem(List<SelectItem> selectItems,Table fromTable) {
//        if (CollectionUtils.isEmpty(selectItems)) {
//            return;
//        }
//        if (selectItems.size() == 1) {
//            SelectItem item = selectItems.get(0);
//            if (item instanceof AllColumns || item instanceof AllTableColumns) {
//                return;
//            }
//        }
//        selectItems.add(new SelectExpressionItem(this.getTenantId(fromTable.getName())));
//    }
//    
//    /**
//    * 描述：在多个select嵌套的sql语句中添加tenant_id的值
//    * @Title: appendTenantIdValue
//    * @param selectItems
//    * @author weiyongpeng
//    * @date  2025年2月1日 上午7:20:30
//     */
//    protected void appendTenantIdValue(List<SelectItem> selectItems) {
//        if (CollectionUtils.isEmpty(selectItems)) {
//            return;
//        }
//        if (selectItems.size() == 1) {
//            SelectItem item = selectItems.get(0);
//            if (item instanceof AllColumns || item instanceof AllTableColumns) {
//                return;
//            }
//        }
//        selectItems.add(new SelectExpressionItem(this.tenantLineHandler.getTenantId()));
//    }
//
//}
